package com.zhangshuo.patternDesign.strategy.common;

import java.io.File;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by shuo.zhang on 2017-10-22.
 */
public class StrategyFactory {


    /**
     * 扫描的基础包名
     */
    private static final String BASE_PACKAGE = "com.zhangshuo.patternDesign.strategy.common";


    /**
     * 默认的类加载器
     */
    private ClassLoader classLoader = this.getClass().getClassLoader();


    /**
     *
     */

    private List<Class<? extends PriceStrategy>> classes = new ArrayList();

    /**
     * 根据不同的价格返回不同的价格策略
     * 但是会出现一堆判断语句，可以使用注解的方法来操作
     *
     * @param
     * @return
     */
/*    public static PriceStrategy createStrategy(Custom custom) {

        if (custom.getTotalAmount() < 1000) {
            return new CommonPriceStrategy();
        }

        if (custom.getTotalAmount() < 2000) {
            return new VipPriceStrategy();
        }

        if (custom.getTotalAmount() < 3000) {
            return new SuperVipPriceStrategy();
        }


        return new GoldenVipPriceStrategy();


    }*/
    public PriceStrategy createStrategy(Custom custom) {

        //Annotation[] annotations;
        TotalValidRegion totalValidRegion = null;
        for (Class<? extends PriceStrategy> clazz : classes) {
            totalValidRegion = handleClass(clazz);
            if (custom.getTotalAmount() >= totalValidRegion.min() && custom.getTotalAmount() < totalValidRegion.max()) {
                try {
                    return clazz.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }


       throw new RuntimeException("获取策略失败");
    }


    /**
     * 处理class 获取注解信息
     * @param clazz
     * @return
     */
    private TotalValidRegion handleClass(Class<? extends PriceStrategy> clazz){
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof TotalValidRegion) {
                return (TotalValidRegion) annotation;

            }
        }

        throw new RuntimeException("处理class信息出错");

    }



    private StrategyFactory() {
        init();
    }

    /**
     * 初始化工具类
     */
    private void init() {
        try {
            initClasses();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 返回扫描目录下的类文件名集合
     *
     * @return
     * @throws Exception
     */
    private File[] getResource() throws Exception {
        File file = new File(classLoader.getResource(BASE_PACKAGE.replaceAll("\\.","/")).toURI());
        return file.listFiles((dir, name) -> {
            return name.endsWith(".class");
        });
    }


    private void initClasses() throws Exception {

        File[] resources = getResource();
        String className;
        for (File resource : resources) {
            className = BASE_PACKAGE + "." + resource.getName().replaceAll("\\.class", "");
            Class clazz;
            try {
                clazz = classLoader.loadClass(className);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }

            if (PriceStrategy.class.isAssignableFrom(clazz) && !clazz.isInterface()) {
                classes.add(clazz);
            }
        }

    }

    /**
     * 单例
     * @return
     */
    public static StrategyFactory instance(){
        return StrategyFactoryInstance.instance;
    }

    private static class StrategyFactoryInstance{
        private static StrategyFactory instance = new StrategyFactory();
    }


}
